Cross-compiling is the process of compiling computer code on one platform (the host system) to create an executable program for a different platform (the target system).
In this perspective, not only the compiling x86_64 binary in an arm-based environment or vice versa, but compiling x86 binary in a x86_64 architecture computer also a cross-compiling.
1. Compile a x86 executable binary in x86_64 environment
Add an option -m32
when using GCC.
gcc -m32 hello.c
And don’t forget to install 32-bit libc library.
sudo dpkg --add-architecture i386
sudo apt update && apt install libc6:i386 libstdc++6:i386
2. Compile an arm architecture executable using gcc
The following example was tested on Ubuntu.
2.1. Install gcc
for the arm architecture
Install arm gcc
to make an arm architecture executable.
sudo apt install gcc-arm-linux-gnueabi
# or
sudo apt install g++-arm-linux-gnueabihf
When you search gcc-arm-linux
, you can see that there are two similar packages that apt
has searched:
$ # Ubuntu 22.04.3 LTS with WSL
$ apt search gcc-arm-linux
Sorting... Done
Full Text Search... Done
gcc-arm-linux-gnueabi/jammy 4:11.2.0-1ubuntu1 amd64
GNU C compiler for the armel architecture
gcc-arm-linux-gnueabihf/jammy 4:11.2.0-1ubuntu1 amd64
GNU C compiler for the armhf architecture
The package that ends with hf
is the package that supports hard float, hardware-assisted float calculation. Most of the case, it would be GPUs.
2.2. Compile
I simply wrote a "Hello World" program in C, the source code file name should be 'hello.c'.
Compile the source code.
arm-linux-gnueabihf-gcc hello.c
Then, there should be an 'a.out' executable.
$ file a.out
a.out: ELF 32-bit LSB pie executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, BuildID[sha1]=a7379f6368c78025791a4887ddc869d8048379fa, for GNU/Linux 3.2.0, not stripped
2.3. Run
$ qemu-arm a.out
Hello World!
2.3.1. "Could not open '/lib/ld-linux-armhf.so.3': No such file or directory"
Sometimes you might see the qemu-arm
program cannot found a proper ld
.
$ qemu-arm a.out
qemu-arm: Could not open '/lib/ld-linux-armhf.so.3': No such file or directory
And you might find there it is somewhere in /usr
directory, not in /lib
.
$ ls /usr/arm-linux-gnueabihf/lib/ld-linux-armhf.so.3
/usr/arm-linux-gnueabihf/lib/ld-linux-armhf.so.3
You can use -L
option to set interpreter ld
path.
$ qemu-arm -L /usr/arm-linux-gnueabihf a.out
Hello World!